import glob
from optparse import OptionParser
import time
import logging
import os
import sys
from datetime import datetime

from pkg_resources import resource_filename

try:
    import json
except ImportError:
    import simplejson as json

import tempita


def get_json(dir):
    for file in glob.glob(dir):
        yield (os.path.basename(file),json.loads(open(file).read())) 

def write_delicious_atom_entry(dest_file_path, template_file,**kwargs):
    tmpl = tempita.Template(open(template_file).read(),name=template_file)
    bunch = tempita.bunch(**kwargs)
    f = open(dest_file_path,'w')
    f.write(tmpl.substitute(bunch))
    f.close()

def main():    
    usage = "usage: %prog [options]"
    parser = OptionParser(usage)

    parser.add_option("-e", "--dest_dir", dest="dest_dir", default="./atom_entries",
    help="Path to dir to store the transformed atom delicious posts. Defaults to\
./atom_entries")
    parser.add_option("-s", "--src_dir",dest="src_dir",default="./delicious_json_posts",
    help="Path to dir that stores the downloaded delicious posts. Defaults to\
./delicious_json_posts")
    parser.add_option("-u", "--post_author", dest="post_author", default="admin",
    help="Author for atom posts. Defaults to admin.")
    parser.add_option("-l","--log",dest="log", default=None, help="Defaults to\
STDOUT")
    parser.add_option("-d","--debug", dest="debug", action='store_true', default=False)
    parser.add_option("-g","--group", dest="group", default='d', help="This\
 parameter determines how delicious posts are grouped\
 before being passed to the template. Grouped entries end\
 up on the same atom entry. Valid values are `d` -\
 group delicious post by day (this is also the default),\
 `i` - not group the entries")
    parser.add_option("-t","--template",
                      dest="template", 
                      default = 'delicious_atom_entry.tmpl',
                      help="The template to use when transforming the json post.\
                      Defaults to 'delicious_atom_entry.tmpl'")
    (options, args) = parser.parse_args()

    if options.log != None:
        logging.basicConfig(level=logging.DEBUG,
                    format='%(asctime)s %(levelname)-8s %(message)s',
                    filename=options.log,
                    filemode='a+')
    else:
        logging.basicConfig(level=logging.DEBUG,
                    format='%(asctime)s %(levelname)-8s %(message)s')
    if options.debug:
        logger = logging.getLogger()
        logger.setLevel(logging.DEBUG)

    options.src_dir = os.path.abspath(options.src_dir)

    #create the dest dir if it does not exist
    if not os.path.exists(options.dest_dir):
        os.makedirs(options.dest_dir)

    #resolve the template location
    if not os.path.exists(options.template):
        #if it does not exist - check if its a packaged template
        options.template = resource_filename(__name__,'templates/'+options.template)
	
        if not os.path.exists(options.template):
            logging.error("Cannot find template '%s'"%options.template)
            sys.exit(1)

    if options.group == 'd':
        collection = {}
        for post_file in glob.glob(os.path.join(options.src_dir,'*.json')):
            post = json.loads(open(post_file).read())        
            key = '-'.join(['%02d'%time_element for time_element in time.strptime(post['time'],'%Y-%m-%dT%H:%M:%SZ')[:3]])

            if not collection.has_key(key):
                collection[key] = []
            collection[key].append(post)
        collection = collection.iteritems()

    elif options.group == 'i':
        collection =  get_json(os.path.join(options.src_dir,'*.json'))

    for item in collection:
        write_delicious_atom_entry(
            os.path.join(options.dest_dir,'%s.atom'%item[0]),
            options.template,
            created=datetime.now().strftime('%Y-%m-%dT%H:%M:%SZ'),
            updated=datetime.now().strftime('%Y-%m-%dT%H:%M:%SZ'),
            username=options.post_author,
            posts=item
            )
        try:
            #we handle the renaming of the src file differently if its the
            #single entry case
            if options.group == 'i':
                post_file = os.path.join(options.src_dir,item[0])
                os.rename(post_file,post_file+'.transformed')
            else:
                [os.rename(post_file,post_file+'.transformed') for post_file in\
                 [os.path.join(options.src_dir,'%s_%s.json'%(post['time'],post['hash']))\
                 for post in item[1]]]
        except OSError,e:
            logging.exception("Failed to rename '%s' to\
                              '%s'"%(post_file,post_file+'.transformed'))
            sys.exit(1)
        logging.info('Adding entry %s'\
                    % (os.path.join(options.dest_dir,'%s.atom'%item[0])))

if __name__ == "__main__":
    main()
